package middleware

import (
	"context"
	"time"

	"github.com/go-kit/kit/endpoint"
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/attribute"
	"go.opentelemetry.io/otel/codes"
	"go.opentelemetry.io/otel/metric"
	"go.opentelemetry.io/otel/trace"
)

func TraceEndpoint(tracer trace.Tracer, operationName string, opts ...trace.SpanStartOption) endpoint.Middleware {
	meter := otel.Meter("addsvc-server")

	return func(next endpoint.Endpoint) endpoint.Endpoint {
		return func(ctx context.Context, request any) (response any, err error) {
			ctx, span := tracer.Start(ctx, operationName, opts...)
			defer span.End()

			defer func(start time.Time) {
				num, _ := meter.Int64Counter(
					"addsvc-server.request.count",
					metric.WithDescription("The number of requests"),
				)
				num.Add(ctx, 1)
				during, _ := meter.Int64Histogram("addsvc-server.request.duration")
				during.Record(ctx, time.Since(start).Milliseconds(), metric.WithAttributes(
					attribute.String("demo", "Duration"),
				))
			}(time.Now())

			defer func() {
				if err != nil {
					span.RecordError(err)
					span.SetStatus(codes.Error, err.Error())
				}
			}()

			return next(ctx, request)
		}
	}
}
